//
// Created by 0209 on 2025/10/28.
//

#include "UdpClient.h"


UdpBackendClient::UdpBackendClient(QObject* parent)
    : QObject(parent)
{
    udpSocket = new QUdpSocket(this);
}

UdpBackendClient::~UdpBackendClient()
{

}

/**
 * @brief 初始化 UDP 客户端并绑定本地端口
 *
 * @param localPort 本地要绑定的 UDP 端口号
 * @return true 绑定成功，可以正常发送/接收数据
 * @return false 绑定失败或 UDP 套接字未创建
 */
bool UdpBackendClient::Udp_Init(quint16 localPort)
{
    //判断UDP是否有套接字
   if (!udpSocket) return false;

    //绑定端口
    this->boundPort = localPort;

    //尝试将UDP绑到本机任意网卡的指定端口
    // QHostAddress::Any 表示绑定到所有可用网卡
    bool ok = udpSocket->bind(QHostAddress::Any, localPort);

    //如果绑定失败返回
    if (! ok)
    {
        return false;
    }

    return true;
}

/*
 * 关闭 UDP 套接字并释放端口
 */
void UdpBackendClient::Udp_Close()
{
    if (!udpSocket) return ;
    if (udpSocket->isOpen())
    {
        udpSocket->close(); //释放端口
    }

    udpSocket->deleteLater();     //延迟销毁对象

    udpSocket = nullptr;
}



/**
 * @brief 通过 UDP 发送数据到指定的远程 IP 和端口
 *
 * @param data      要发送的数据，QByteArray 格式
 * @param remoteIp  目标主机的 IP 地址，QString 格式
 * @param remotePort 目标主机的端口号
 *
 * @note 该函数会检查 udpSocket 是否已初始化，如果未初始化则直接返回。
 *       使用 QHostAddress 将 IP 字符串转换为可用的地址。
 *       数据通过 QUdpSocket::writeDatagram 发送。
 */
void UdpBackendClient::Udp_sendData(const QByteArray& data, const QString& remoteIp, quint16 remotePort)
{
    if (!udpSocket)
        return;
    udpSocket->writeDatagram(data, QHostAddress(remoteIp), remotePort);
}

/*
 * 判断UDP是否打开
 */
bool UdpBackendClient::Udp_IsOpen() const
{
    return isOpen && udpSocket && udpSocket->isOpen();
}


/*
 * 获取 UDP 错误信息
 */
QString UdpBackendClient::Udp_ErrorString() const
{
    if (!udpSocket) {
        return "UDP 套接字未初始化";
    }

    // 如果当前已绑定（说明处于正常状态），返回空字符串表示无错误
    if (udpSocket->state() == QAbstractSocket::BoundState) {
        return QString();  // 没有错误
    }

    // 根据 QAbstractSocket::SocketError 枚举返回更友好的提示
    switch (udpSocket->error()) {
    case QAbstractSocket::ConnectionRefusedError:
        return "连接被拒绝，请检查目标地址或端口";
    case QAbstractSocket::RemoteHostClosedError:
        return "远程主机关闭连接";
    case QAbstractSocket::HostNotFoundError:
        return "找不到主机，请检查 IP 地址";
    case QAbstractSocket::SocketAccessError:
        return "UDP 访问被拒绝，无权限操作";
    case QAbstractSocket::SocketResourceError:
        return "系统资源不足，无法创建 UDP 套接字";
    case QAbstractSocket::SocketTimeoutError:
        return "UDP 操作超时";
    case QAbstractSocket::DatagramTooLargeError:
        return "发送的数据包过大";
    case QAbstractSocket::NetworkError:
        return "网络发生错误，请检查网络连接";
    case QAbstractSocket::AddressInUseError:
        return "端口已被占用，请更换本地端口";
    case QAbstractSocket::SocketAddressNotAvailableError:
        return "指定的本地地址不可用";
    case QAbstractSocket::UnsupportedSocketOperationError:
        return "系统不支持此 UDP 操作";
    case QAbstractSocket::UnfinishedSocketOperationError:
        return "UDP 操作未完成，请稍后重试";
    case QAbstractSocket::ProxyAuthenticationRequiredError:
        return "需要代理身份验证";
    case QAbstractSocket::UnknownSocketError:
    default:
        return udpSocket->errorString();  // 使用 Qt 自带错误描述
    }
}





